#include<iostream>
#include<vector>
#include<mutex>
#include<pthread.h>
//#include"lockGuard.hpp"
#include"Thread.hpp"
using namespace ThreadModule;


class ThreadData
{
public:
    ThreadData(int &tickets,const std::string &name,std::mutex &mutex)
        :_tickets(tickets)
        ,_name(name)
        ,_touta(0)
        ,_mutex(mutex)
    {}
    ~ThreadData()
    {}
public:
int &_tickets;
std::string _name;
int _touta;
std::mutex &_mutex;
};

//pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
int g_tickets = 10000;

void route(ThreadData *td)
{
    while (true)
    {
      //LockGuard guard(&td->_mutex);//raii风格
       //一下是临界区------------------
       //td->_mutex.lock();
       //如系统调用
       std::lock_guard<std::mutex>lock(td->_mutex);
      if(td->_tickets>0)
      {
        usleep(1000);
        printf("%s running get tickets:%d\n",td->_name.c_str(),td->_tickets);
        td->_tickets--;
       // pthread_mutex_unlock(&gmutex);
       //以上所以临界区--------------
      
       //下一是非临界区
        td->_touta++;
       // td->_mutex.unlock();
      }
      else
      {
        //td->_mutex.unlock();
        break;;
      }
    }
    
}

const int num = 4;
//这是c++11
int main()
{
    std::mutex mutex;
    // pthread_mutex_t mutex;
    // pthread_mutex_init(&mutex,nullptr);
    std::vector<Thread<ThreadData *>>threads;
    std::vector<ThreadData *> datas;
    //创建
    for(int i =0;i<num;i++)
    {
        std::string name ="thread-"+std::to_string(i+1);
        ThreadData *td = new ThreadData(g_tickets,name,mutex);
        threads.emplace_back(route,td,name);
        datas.emplace_back(td);
    }
    //启动
    for(auto &thread :threads)
    {
        thread.Start();
    }
    //等待
    for(auto &thread:threads)
    {
        thread.Join();
       // std::cout<<"等待线程，线程是："<<thread.name()<<std::endl;
    }
    //统计
    for(auto data:datas)
    {
        std::cout<<data->_name<<data->_touta<<std::endl;
    }
    //pthread_mutex_destroy(&mutex);
    return 0;
}

//一下是系统提供的锁
// class ThreadData
// {
// public:
//     ThreadData(int &tickets,const std::string &name,pthread_mutex_t &mutex)
//         :_tickets(tickets)
//         ,_name(name)
//         ,_touta(0)
//         ,_mutex(mutex)
//     {}
//     ~ThreadData()
//     {}
// public:
// int &_tickets;
// std::string _name;
// int _touta;
//  pthread_mutex_t &_mutex;
// };

// //pthread_mutex_t gmutex = PTHREAD_MUTEX_INITIALIZER;
// int g_tickets = 10000;

// void route(ThreadData *td)
// {
//     while (true)
//     {
//       LockGuard guard(&td->_mutex);//raii风格
//        //一下是临界区------------------
//       if(td->_tickets>0)
//       {
//         usleep(1000);
//         printf("%s running get tickets:%d\n",td->_name.c_str(),td->_tickets);
//         td->_tickets--;
//        // pthread_mutex_unlock(&gmutex);
//        //以上所以临界区--------------
      
//        //下一是非临界区
//         td->_touta++;
//       }
//       else
//       {
       
//         break;;
//       }
//     }
    
// }

// void route(ThreadData *td)
// {
//     while (true)
//     {
//        // pthread_mutex_lock(&gmutex);
//        pthread_mutex_lock(&td->_mutex);
//        //一下是临界区------------------
//       if(td->_tickets>0)
//       {
//         usleep(1000);
//         printf("%s running get tickets:%d\n",td->_name.c_str(),td->_tickets);
//         td->_tickets--;
//        // pthread_mutex_unlock(&gmutex);
//        //以上所以临界区--------------
//        pthread_mutex_unlock(&td->_mutex);
//        //下一是非临界区
//         td->_touta++;
//       }
//       else
//       {
//         pthread_mutex_unlock(&td->_mutex);
//       //  pthread_mutex_unlock(&gmutex);
//         break;;
//       }
//     }
    
// }
// const int num = 4;
// int main()
// {
//     pthread_mutex_t mutex;
//     pthread_mutex_init(&mutex,nullptr);
//     std::vector<Thread<ThreadData *>>threads;
//     std::vector<ThreadData *> datas;
//     //创建
//     for(int i =0;i<num;i++)
//     {
//         std::string name ="thread-"+std::to_string(i+1);
//         ThreadData *td = new ThreadData(g_tickets,name,mutex);
//         threads.emplace_back(route,td,name);
//         datas.emplace_back(td);
//     }
//     //启动
//     for(auto &thread :threads)
//     {
//         thread.Start();
//     }
//     //等待
//     for(auto &thread:threads)
//     {
//         thread.Join();
//        // std::cout<<"等待线程，线程是："<<thread.name()<<std::endl;
//     }
//     //统计
//     for(auto data:datas)
//     {
//         std::cout<<data->_name<<data->_touta<<std::endl;
//     }
//     pthread_mutex_destroy(&mutex);
//     return 0;
// }